﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Net.Mime.MediaTypeNames;
using static System.Windows.Forms.AxHost;

namespace BarrageGameAssistant.Controls
{
    public partial class CapturePictureBox : UserControl
    {
        private Point _mouseXY;
        private Rectangle _zoomRect;
        private bool _mouseEnterFlag;
        private Rectangle _box = new();
        private bool _draggingFlag;

        public List<Rectangle>? DrawRectangles { get; set; }

        /// <summary>
        /// 绘制十字线
        /// </summary>
        [Description("绘制十字线")]
        public bool DrawCrosshair { get; set; }

        /// <summary>
        /// 绘制十字线颜色
        /// </summary>
        [Description("绘制十字线颜色")]
        public Color CrosshairColor { get; set; } = Color.Yellow;

        /// <summary>
        /// 绘制十字线
        /// </summary>
        [Description("绘制矩形")]
        public bool DrawRectangle { get; set; }

        /// <summary>
        /// 绘制矩形颜色
        /// </summary>
        [Description("绘制矩形颜色")]
        public Color DrawRectangleColor { get; set; } = Color.Yellow;

        /// <summary>
        /// 放大预览
        /// </summary>
        [Description("放大预览")]
        public PictureBox? ZoomPreview { get; set; }

        /// <summary>
        /// 
        /// </summary>
        [DefaultValue(typeof(Size), "260, 260")]
        public Size ZoomPreviewSize { get; set; } = new Size(260, 260);

        /// <summary>
        /// 修正显示像素
        /// </summary>
        [Description("修正显示像素")]
        public int FixDisplayPixel { get; set; } = 2;

        /// <summary>
        /// 图片尺寸改变事件
        /// </summary>
        [Description("图片尺寸改变事件")]
        public event EventHandler<Size>? OnPictureSizeChanged;

        /// <summary>
        /// 鼠标位置
        /// </summary>
        [Description("鼠标位置")]
        public event EventHandler<Point>? MouseLocation;

        /// <summary>
        /// 矩形选择完毕事件
        /// </summary>
        [Description("矩形选择完毕事件")]
        public event EventHandler<Rectangle>? SelectedRectangle;

        /// <summary>
        /// 坐标选择完毕事件
        /// </summary>
        [Description("坐标选择完毕事件")]
        public event EventHandler<Point>? SelectedPoint;

        public CapturePictureBox()
        {
            InitializeComponent();
        }

        private void CapturePictureBox_Load(object sender, EventArgs e)
        {
            if (this.Parent != null)
                this.Parent.SizeChanged += Parent_SizeChanged;

            if (ZoomPreview != null)
            {
                _zoomRect = new Rectangle(0, 0, ZoomPreviewSize.Width, ZoomPreviewSize.Height);
                ZoomPreview.Size = ZoomPreviewSize;
                ZoomPreview.Paint += ZoomPreview_Paint;
            }
        }

        private void ZoomPreview_Paint(object? sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            try
            {
                if (this.pbMain.Image != null)
                {
                    g.DrawImage(this.pbMain.Image, _zoomRect, new Rectangle(_mouseXY.X - 80, _mouseXY.Y - 80, 160, 160), GraphicsUnit.Pixel);
                }

                Pen pen = new(Color.Yellow, 1); // 设定红色、1px宽度的画笔
                g.DrawLine(pen, ZoomPreviewSize.Height / 2, 0, ZoomPreviewSize.Height / 2, this.Height);
                g.DrawLine(pen, 0, ZoomPreviewSize.Width / 2, this.Width, ZoomPreviewSize.Width / 2);
            }
            catch (Exception)
            {
            }
        }

        /// <summary>
        /// 刷新位置
        /// </summary>
        private void RefreshLocation()
        {
            if (this.Parent != null)
            {
                if (this.Parent is SplitterPanel pnl)
                    this.Location = new System.Drawing.Point(pnl.Width / 2 - this.Width / 2, pnl.Height / 2 - this.Height / 2);
            }
        }

        private void Parent_SizeChanged(object? sender, EventArgs e)
        {
            RefreshLocation();
        }

        /// <summary>
        /// 设置图片大小
        /// </summary>
        /// <param name="size"></param>
        public void SetSize(Size size)
        {
            this.Size = size;
            RefreshLocation();
            OnPictureSizeChanged?.Invoke(this, this.pbMain.Size);
        }

        /// <summary>
        /// 设置图像
        /// </summary>
        /// <param name="image"></param>
        public void SetImage(Bitmap image)
        {
            SetSize(new Size(image.Size.Width + FixDisplayPixel, image.Size.Height + FixDisplayPixel));
            pbMain.Image = image;
        }

        private System.Drawing.Image GetImage(string path, out Size size)
        {
            using FileStream fs = new(path, FileMode.Open, FileAccess.Read);
            System.Drawing.Image result = System.Drawing.Image.FromStream(fs);
            size = result.Size;
            fs.Close();
            return result;
        }

        private System.Drawing.Image? GetImageObject(string path)
        {
            using System.Drawing.Image image = System.Drawing.Image.FromFile(path);
            return image.Clone() as System.Drawing.Image;
        }

        public void SetImage(string imagePath)
        {
            Size size;
            pbMain.Image = GetImage(imagePath, out size);
            SetSize(new Size(size.Width + FixDisplayPixel, size.Height + FixDisplayPixel));
        }

        private void pbMain_MouseMove(object sender, MouseEventArgs e)
        {
            _mouseXY = e.Location;

            MouseLocation?.Invoke(this, e.Location);
            pbMain.Refresh();

            ZoomPreview?.Refresh();
        }

        private void pbMain_Paint(object sender, PaintEventArgs e)
        {
            Graphics g = e.Graphics;

            //显示预设的绘制选择框
            if (DrawRectangles != null)
            {
                foreach (var cap in DrawRectangles)
                {
                    Pen pen1 = new(Color.Yellow, 2);
                    g.DrawRectangle(pen1, new Rectangle(cap.X, cap.Y, cap.Width, cap.Height));
                }
            }

            //绘制坐标十字线
            if (pbMain.Image != null && _mouseEnterFlag && DrawCrosshair)
            {
                Pen pen = new(CrosshairColor, 1); // 设定红色、1px宽度的画笔
                g.DrawLine(pen, _mouseXY.X, 0, _mouseXY.X, this.Height);
                g.DrawLine(pen, 0, _mouseXY.Y, this.Width, _mouseXY.Y);
            }

            if (pbMain.Image != null && _mouseEnterFlag && DrawRectangle)
            {
                //Pen pen = new(DrawRectangleColor, 1); // 设定红色、1px宽度的画笔
                //g.DrawLine(pen, _mouseXY.X, 0, _mouseXY.X, this.Height);
                //g.DrawLine(pen, 0, _mouseXY.Y, this.Width, _mouseXY.Y);

                //判断是否要绘制选择框
                if (_draggingFlag)
                {
                    _box.Width = _mouseXY.X - _box.X;
                    _box.Height = _mouseXY.Y - _box.Y;
                    Pen pen1 = new(DrawRectangleColor, 2);
                    g.DrawRectangle(pen1, _box);
                    //SolidBrush brush = new SolidBrush(Color.Red);
                    //g.FillRectangle(brush, _box);
                }
            }
        }

        public void ClearDrawRectangles()
        {
            DrawRectangles?.Clear();
        }

        private void pbMain_MouseEnter(object sender, EventArgs e)
        {
            _mouseEnterFlag = true;
            DrawRectangles?.Clear();
        }

        private void pbMain_MouseLeave(object sender, EventArgs e)
        {
            _mouseEnterFlag = false;
        }

        private void pbMain_MouseDown(object sender, MouseEventArgs e)
        {
            _draggingFlag = true;
            _box.X = e.X; _box.Y = e.Y;
        }

        private void pbMain_MouseUp(object sender, MouseEventArgs e)
        {
            _draggingFlag = false;
            _box.Width = _mouseXY.X - _box.X;
            _box.Height = _mouseXY.Y - _box.Y;

            if (pbMain.Image != null && _box.Width > 5 && _box.Height > 5)
                SelectedRectangle?.Invoke(this, _box);

            if (pbMain.Image != null && DrawCrosshair && !DrawRectangle)
                SelectedPoint?.Invoke(this, e.Location);
        }
    }
}
